/*******************************************************************
 *
 * Copyright (C), 2021-2022, Letstrong, All rights reserved.
 *
 * Author      : 
 * Create Time : 2020-12-14
 * Version     : v0.1
 * Description : 
 *******************************************************************/
 
/*----------------------------Head file----------------------------*/
#include "rwip_config.h"

#if (BLE_USER_SENSOR)

#include "gap.h"
#include "ke_timer.h"
#include "app_task.h"
#include "gattc_task.h"
#include "prf_utils.h"
#include "co_utils.h"
#include "user.h"
#include "user_task.h"
#include "user_protocol.h"
#include "app_global_data.h"
#include "sys_task.h"

#define USER_TASK_LOG_ENABLE		1

#if USER_TASK_LOG_ENABLE
#include "log.h"
#define USER_TASK_LOG				LOG_DEBUG
#else
#define USER_TASK_LOG(...)
#endif

/*----------------------------macro file---------------------------*/

/*----------------------------type define--------------------------*/

/*----------------------------var define---------------------------*/

/*-------------------------func declaration------------------------*/

/*-----------------------------------------------------------------*/

/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_write_req_ind_handler(ke_msg_id_t const msgid,
                                      struct gattc_write_req_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
	struct gattc_write_cfm * cfm;
	int msg_status = KE_MSG_CONSUMED;
	uint8_t status = ATT_ERR_NO_ERROR;
    uint8_t conidx = KE_IDX_GET(src_id);
	
	//USER_TASK_LOG("user gattc_write_req_ind_handler\n");
	if(ke_state_get(dest_id) == USER_IDLE)
    {
		struct user_env_tag* user_env = PRF_ENV_GET(USER, user);
		//USER_TASK_LOG("idx: %d\n", (param->handle - user_env->start_hdl));
		if (param->handle == (user_env->start_hdl + USER_IDX_WRITE_VAL))
		{
			ble_rope_client_write_rsp(param->value, param->length);
			USER_TASK_LOG("USER_IDX_WRITE_VAL: %d.\n", param->length);
		}
		else if(param->handle == (user_env->start_hdl + USER_IDX_IND_CFG))
		{
			uint16_t ind_cfg = co_read16p(&param->value[0]);
			USER_TASK_LOG("USER_IDX_IND_CFG = %d\r\n", ind_cfg);
			if (ind_cfg == PRF_CLI_START_IND)
			{
#if UPDATE_CONNENCT_PARAM
#if(ROPE_CENTRAL_SUP_ENABLE)
				ke_timer_set(APP_PARAM_UPDATE_REQ_IND, TASK_APP, 10);	//Update conn param to make more compatible to android phone app.
#endif
#endif
				user_env->ind_cfg[conidx] = USER_IND_SUP;	// Indicate cfg bit set to 1
				g_app_data.sys.ble_conn_type = BLE_CONN_TYPE_PHONE_APP;
				sys_task_evt_set(SYS_EVT_BLE_UPLOAD_BATT_PER);
			}
			else
			{
				user_env->ind_cfg[conidx] = USER_IND_NOT_SUP;	// Indicate cfg bit set to 0
			}
		}
		//Send write response
		cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm);
		cfm->handle = param->handle;
		cfm->status = status;
		ke_msg_send(cfm);
	}
	else if(ke_state_get(dest_id) == USER_BUSY)
    {
      	msg_status = KE_MSG_SAVED;
    }
	
    return (msg_status);
}


/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_READ_REQ_IND message.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_read_req_ind_handler(ke_msg_id_t const msgid, struct gattc_read_req_ind const *param,
                                      ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
	//Note: It need PERM(RI, ENABLE) in blps_att_db to trigger this handler.
	struct gattc_read_cfm * cfm;
	int msg_status = KE_MSG_CONSUMED;
	uint8_t status = ATT_ERR_NO_ERROR;
	// retrieve handle information
	uint16_t length = 0;
	struct user_env_tag* user_env = PRF_ENV_GET(USER, user);
	ke_state_t state = ke_state_get(dest_id);
	uint8_t value[20] = {0};

	if(ke_state_get(dest_id) == USER_IDLE)
	{
		//Send read response
		cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length);
		memcpy(cfm->value, value, length);
		cfm->handle = param->handle;
		cfm->status = status;
		cfm->length = length;
		
		ke_msg_send(cfm);
	}
	else if(ke_state_get(dest_id) == USER_BUSY)
	{
		msg_status = KE_MSG_SAVED;
	}

    return (msg_status);
}


/**
 ****************************************************************************************
 * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY and GATT_INDICATE message meaning
 * that Measurement notification/indication has been correctly sent to peer device
 *
 *
 * @param[in] msgid     Id of the message received.
 * @param[in] param     Pointer to the parameters of the message.
 * @param[in] dest_id   ID of the receiving task instance
 * @param[in] src_id    ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_cmp_evt_handler(ke_msg_id_t const msgid,  struct gattc_cmp_evt const *param,
                                 ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
	//USER_TASK_LOG("app_user_gattc_cmp_evt_handler: %d, %d, (%d).\r\n", GATTC_CMP_EVT, msgid, GATTC_ATT_INFO_CFM);
    if(param->operation == GATTC_INDICATE && param->status == GAP_ERR_NO_ERROR)
	{
		//USER_TASK_LOG("GATTC_INDICATE.\r\n");
		user_upload_info_to_app_process(SKIP_CMD_REST_DATA);
	}

    return (KE_MSG_CONSUMED);
}



/*
 * GLOBAL VARIABLE DEFINITIONS
 ****************************************************************************************
 */

/// Default State handlers definition
const struct ke_msg_handler user_default_state[] =
{
    {GATTC_WRITE_REQ_IND,   	(ke_msg_func_t) gattc_write_req_ind_handler},
	{GATTC_READ_REQ_IND,		(ke_msg_func_t) gattc_read_req_ind_handler},
	{GATTC_CMP_EVT,         	(ke_msg_func_t) gattc_cmp_evt_handler},
};

/// Specifies the message handlers that are common to all states.
const struct ke_state_handler user_default_handler = KE_STATE_HANDLER(user_default_state);

#endif /* #if (BLE_USER_SENSOR) */

/// @} USER_TASK
